home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / winsock / ircii2-6.zip / SRC\IRCII-2.6\SOURCE\SERVER.C < prev    next >
C/C++ Source or Header  |  1995-01-09  |  38KB  |  1,631 lines

  1. /*
  2.  * server.c: Things dealing with server connections, etc. 
  3.  *
  4.  * Written By Michael Sandrof
  5.  *
  6.  * Copyright(c) 1990 
  7.  *
  8.  * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT 
  9.  */
  10.  
  11. #ifndef lint
  12. static    char    rcsid[] = "@(#)$Id: server.c,v 1.27 1994/10/17 11:52:55 mrg Exp $";
  13. #endif
  14.  
  15. #include "irc.h"
  16.  
  17. #ifdef ESIX
  18. # include <lan/net_types.h>
  19. #endif /* ESIX */
  20.  
  21. #ifdef HAVE_SYS_UN_H
  22. # include <sys/un.h>
  23.     int    connect_to_unix();
  24. #endif /* HAVE_SYS_UN_H */
  25.  
  26. #include "server.h"
  27. #include "ircaux.h"
  28. #include "whois.h"
  29. #include "lastlog.h"
  30. #include "exec.h"
  31. #include "window.h"
  32. #include "output.h"
  33. #include "names.h"
  34. #include "parse.h"
  35. #include "screen.h"
  36.  
  37. static    void    add_to_server_buffer __P((int, char *));
  38.  
  39. /*
  40.  * Don't want to start ircserv by default...
  41.  */
  42.     int    using_server_process = 0;
  43.  
  44. /* server_list: the list of servers that the user can connect to,etc */
  45.     Server    *server_list = (Server *) 0;
  46.  
  47. /* number_of_servers: in the server list */
  48.     int    number_of_servers = 0;
  49.  
  50. extern    WhoisQueue    *WQ_head;
  51. extern    WhoisQueue    *WQ_tail;
  52.  
  53.     int    primary_server = -1;
  54.     int    from_server = -1;
  55.     int    attempting_to_connect= 0;
  56.     int    never_connected = 1;        /* true until first connection
  57.                          * is made */
  58.     int    connected_to_server = 0;    /* true when connection is
  59.                          * confirmed */
  60.     char    *connect_next_nick;
  61.     int    parsing_server_index = -1;
  62.  
  63. extern    int    dgets_errno;
  64.  
  65. /*
  66.  * Why this as well as MyHostAddr? Well, if your host is a gateway, this
  67.  * will be set to the address for your host which is nearest to everybody
  68.  * else on IRC in most circumstances. Thus it is most useful for DCC
  69.  * connections telling other clients where you are. MyHostAddr holds the
  70.  * first address returned by the name server, which may or may not be best,
  71.  * but is used in things like talk where the behaviour should mimic the
  72.  * standard programs.
  73.  *
  74.  * None of this applies if you are using ircserv. In this case, local_ip_address
  75.  * is the same as MyHostAddr.
  76.  */
  77. /* extern    struct    in_addr    local_ip_address; */ /* moved to irc.h */
  78.  
  79. /*
  80.  * close_server: Given an index into the server list, this closes the
  81.  * connection to the corresponding server.  It does no checking on the
  82.  * validity of the index.  It also first sends a "QUIT" to the server being
  83.  * closed 
  84.  */
  85. void
  86. close_server(index, message)
  87.     int    index;
  88.     char    *message;
  89. {
  90.     int    i,
  91.         min,
  92.         max;
  93.  
  94.     if (index == -1)
  95.     {
  96.         min = 0;
  97.         max = number_of_servers;
  98.     }
  99.     else
  100.     {
  101.         min = index;
  102.         max = index + 1;
  103.     }
  104.     for (i = min; i < max; i++)
  105.     {
  106.         if (i == primary_server)
  107.         {
  108.         /* make sure no leftover whois's are out there */
  109.             clean_whois_queue();
  110.             if (waiting)
  111.                 irc_io_loop = 0;
  112.             set_waiting_channel(i);
  113.         }
  114.         else
  115.             clear_channel_list(i);
  116.         server_list[i].operator = 0;
  117.         server_list[i].connected = 0;
  118.         server_list[i].buffer = (char *) 0;
  119.         if (-1 != server_list[i].write)
  120.         {
  121.             if (message && *message)
  122.             {
  123.                 sprintf(buffer, "QUIT :%s\n", message);
  124.                 send(server_list[i].write, buffer, strlen(buffer), 0);
  125.             }
  126.             new_close(server_list[i].write);
  127.             if (server_list[i].write == server_list[i].read)
  128.                 server_list[i].read = -1;
  129.             server_list[i].write = -1;
  130.         }
  131.         if (-1 != server_list[i].read)
  132.         {
  133.             new_close(server_list[i].read);
  134.             server_list[i].read = -1;
  135.         }
  136. #ifndef _Windows
  137.         if (-1 != server_list[i].pid)
  138.         {
  139.             kill(server_list[i].pid, SIGKILL);
  140.             server_list[i].pid = (pid_t) -1;
  141.         }
  142. #endif
  143.     }
  144. }
  145.  
  146. /*
  147.  * set_server_bits: Sets the proper bits in the fd_set structure according to
  148.  * which servers in the server list have currently active read descriptors.  
  149.  */
  150.  
  151. void
  152. set_server_bits(rd)
  153.     fd_set *rd;
  154. {
  155.     int    i;
  156.  
  157.     for (i = 0; i < number_of_servers; i++)
  158.         if (server_list[i].read != -1)
  159.             FD_SET(server_list[i].read, rd);
  160. }
  161.  
  162. /*
  163.  * do_server: check the given fd_set against the currently open servers in
  164.  * the server list.  If one have information available to be read, it is read
  165.  * and and parsed appropriately.  If an EOF is detected from an open server,
  166.  * one of two things occurs. 1) If the server was the primary server,
  167.  * get_connected() is called to maintain the connection status of the user.
  168.  * 2) If the server wasn't a primary server, connect_to_server() is called to
  169.  * try to keep that connection alive. 
  170.  */
  171.  
  172. void
  173. do_server(rd)
  174.     fd_set    *rd;
  175. {
  176.     define_big_buffer(buffer);
  177.     int    des,
  178.         i;
  179.     static    int    times = 0;
  180.     int    old_timeout;
  181.  
  182.     for (i = 0; i < number_of_servers && !break_io_processing; i++)
  183.     {
  184.         if ((des = server_list[i].read) != -1 && FD_ISSET(des, rd))
  185.         {
  186.             int    junk;
  187.             char     *bufptr;
  188.             char    *s;
  189.  
  190.             from_server = i;
  191.             old_timeout = dgets_timeout(2);
  192.             s = server_list[from_server].buffer;
  193.             bufptr = buffer;
  194.             if (s && *s)
  195.             {
  196.                 int    len = strlen(s);
  197.  
  198.                 strncpy(buffer, s, len);
  199.                 bufptr += len;
  200.             }
  201.             do
  202.             {
  203.                 junk = dgets(bufptr, BIG_BUFFER_SIZE, des, (char *) 0);
  204.                 switch (junk)
  205.                 {
  206.                 case -1:
  207.     #ifdef PHONE
  208.                     say("server %s: dgets timed out.  continuing...(%s)", server_list[i].name, bufptr);
  209.     #endif
  210.                     add_to_server_buffer(from_server, buffer);
  211.                     continue;
  212.                     break;
  213.                 case 0:
  214.                     close_server(i, empty_string);
  215.                     say("Connection closed from %s: %s", server_list[i].name,
  216.                         dgets_errno ? strerror(dgets_errno) : "connection timed out");
  217.                     if (i == primary_server)
  218.                     {
  219.                         if (server_list[i].eof)
  220.                         {
  221.                             say("Unable to connect to server %s",
  222.                                 server_list[i].name);
  223.                             if (++i == number_of_servers)
  224.                             {
  225.                                 clean_whois_queue();
  226.                                 say("Use /SERVER to connect to a server");
  227.                                 times = 0;
  228.                             }
  229.                             else
  230.                                 get_connected(i);
  231.                         }
  232.                         else
  233.                         {
  234.                             if (times++ > 1)
  235.                             {
  236.                                 clean_whois_queue();
  237.                                 say("Use /SERVER to connect to a server");
  238.                                 times = 0;
  239.                             }
  240.                             else
  241.                                 get_connected(i);
  242.                         }
  243.                     }
  244.                     else if (server_list[i].eof)
  245.                     {
  246.                         say("Connection to server %s lost.",
  247.                             server_list[i].name);
  248.                         close_server(i, empty_string);
  249.                         clean_whois_queue();
  250.                         window_check_servers();
  251.                     }
  252.                     else if (connect_to_server(server_list[i].name,
  253.                             server_list[i].port, -1))
  254.                     {
  255.                         say("Connection to server %s lost.",
  256.                             server_list[i].name);
  257.                         close_server(i, empty_string);
  258.                         clean_whois_queue();
  259.                         window_check_servers();
  260.                     }
  261.                     server_list[i].eof = 1;
  262.                     break;
  263.                 default:
  264.                     parsing_server_index = i;
  265.                     parse_server(buffer);
  266.                     new_free(&server_list[i].buffer);
  267.                     parsing_server_index = -1;
  268.                     message_from((char *) 0, LOG_CRAP);
  269.                     break;
  270.                 }
  271.                 (void) dgets_timeout(0);
  272.             } while (junk > 0);
  273.             (void) dgets_timeout(old_timeout);
  274.             from_server = primary_server;
  275.         }
  276.     }
  277.     free_big_buffer(buffer);
  278. }
  279.  
  280. /*
  281.  * find_in_server_list: given a server name, this tries to match it against
  282.  * names in the server list, returning the index into the list if found, or
  283.  * -1 if not found 
  284.  */
  285. extern    int
  286. find_in_server_list(server, port)
  287.     char    *server;
  288.     int    port;
  289. {
  290.     int    i,
  291.         len,
  292.         len2;
  293.  
  294.     len = strlen(server);
  295.     for (i = 0; i < number_of_servers; i++)
  296.     {
  297.         if (port && server_list[i].port && port != server_list[i].port)
  298.             continue;
  299.         len2 = strlen(server_list[i].name);
  300.         if (len2 > len)
  301.         {
  302.             if (!my_strnicmp(server, server_list[i].name, len))
  303.                 return (i);
  304.         }
  305.         else
  306.         {
  307.             if (!my_strnicmp(server, server_list[i].name, len2))
  308.                 return (i);
  309.         }
  310.     }
  311.     return (-1);
  312. }
  313.  
  314. /*
  315.  * parse_server_index:  given a string, this checks if it's a number, and if
  316.  * so checks it validity as a server index.  Otherwise -1 is returned 
  317.  */
  318. int
  319. parse_server_index(str)
  320.     char    *str;
  321. {
  322.     int    i;
  323.  
  324.     if (is_number(str))
  325.     {
  326.         i = atoi(str);
  327.         if ((i >= 0) && (i < number_of_servers))
  328.             return (i);
  329.     }
  330.     return (-1);
  331. }
  332.  
  333. /*
  334.  * get_server_index: Given a string, this checks first to see if that string
  335.  * represents an integer.  If so, it is checked for validity as a server
  336.  * index and returned.  If the string is not an integer,
  337.  * find_in_server_list() is called and it's value returned.  -1 is returned
  338.  * if an invalid interger is used 
  339.  */
  340. int
  341. get_server_index(name)
  342.     char    *name;
  343. {
  344.     int    i;
  345.  
  346.     if ((i = parse_server_index(name)) == -1)
  347.         return (find_in_server_list(name, 0));
  348.     else
  349.         return (i);
  350. }
  351.  
  352. /*
  353.  * add_to_server_list: adds the given server to the server_list.  If the
  354.  * server is already in the server list it is not re-added... however, if the
  355.  * overwrite flag is true, the port and passwords are updated to the values
  356.  * passes.  If the server is not on the list, it is added to the end. In
  357.  * either case, the server is made the current server. 
  358.  */
  359. void
  360. add_to_server_list(server, port, password, nick, overwrite)
  361.     char    *server;
  362.     int    port;
  363.     char    *password;
  364.     char    *nick;
  365.     int    overwrite;
  366. {
  367.     if ((from_server = find_in_server_list(server, port)) == -1)
  368.     {
  369.         from_server = number_of_servers++;
  370.         if (server_list)
  371.             server_list = (Server *) new_realloc(server_list,
  372.                 number_of_servers * sizeof(Server));
  373.         else
  374.             server_list = (Server *) new_malloc(number_of_servers
  375.                 * sizeof(Server));
  376.         server_list[from_server].name = (char *) 0;
  377.         server_list[from_server].itsname = (char *) 0;
  378.         server_list[from_server].password = (char *) 0;
  379.         server_list[from_server].away = (char *) 0;
  380.         server_list[from_server].version_string = (char *) 0;
  381.         server_list[from_server].operator = 0;
  382.         server_list[from_server].read = -1;
  383.         server_list[from_server].write = -1;
  384.         server_list[from_server].pid = -1;
  385.         server_list[from_server].version = 0;
  386.         server_list[from_server].whois = 0;
  387.         server_list[from_server].flags = SERVER_2_6_2;
  388.         server_list[from_server].nickname = (char *) 0;
  389.         server_list[from_server].connected = 0;
  390.         server_list[from_server].eof = 0;
  391.         server_list[from_server].motd = 1;
  392.         malloc_strcpy(&(server_list[from_server].name), server);
  393.         if (password && *password)
  394.             malloc_strcpy(&(server_list[from_server].password),
  395.                 password);
  396.         if (nick && *nick)
  397.             malloc_strcpy(&(server_list[from_server].nickname),
  398.                 nick);
  399.         server_list[from_server].port = port;
  400.         server_list[from_server].WQ_head = (WhoisQueue *) 0;
  401.         server_list[from_server].WQ_tail = (WhoisQueue *) 0;
  402.         server_list[from_server].whois_stuff.nick = (char *) 0;
  403.         server_list[from_server].whois_stuff.user = (char *) 0;
  404.         server_list[from_server].whois_stuff.host = (char *) 0;
  405.         server_list[from_server].whois_stuff.channel = (char *) 0;
  406.         server_list[from_server].whois_stuff.channels = (char *) 0;
  407.         server_list[from_server].whois_stuff.name = (char *) 0;
  408.         server_list[from_server].whois_stuff.server = (char *) 0;
  409.         server_list[from_server].whois_stuff.server_stuff =
  410.             (char *) 0;
  411.         server_list[from_server].whois_stuff.away = (char *) 0;
  412.         server_list[from_server].whois_stuff.oper = 0;
  413.         server_list[from_server].whois_stuff.chop = 0;
  414.         server_list[from_server].whois_stuff.not_on = 0;
  415.         server_list[from_server].buffer = (char *) 0;
  416.     }
  417.     else
  418.     {
  419.         if (overwrite)
  420.         {
  421.             server_list[from_server].port = port;
  422.             if (password || !server_list[from_server].password)
  423.             {
  424.                 if (password && *password)
  425.         malloc_strcpy(&(server_list[from_server].password), password);
  426.                 else
  427.         new_free(&(server_list[from_server].password));
  428.             }
  429.         }
  430.         if (strlen(server) > strlen(server_list[from_server].name))
  431.             malloc_strcpy(&(server_list[from_server].name), server);
  432.     }
  433. }
  434.  
  435. static    void
  436. remove_from_server_list(i)
  437.     int    i;
  438. {
  439.     int    old_server = from_server,
  440.         flag = 1;
  441.     Window    *tmp;
  442.     TravInfo ti;
  443.  
  444.     from_server = i;
  445.     clean_whois_queue();
  446.     from_server = old_server;
  447.  
  448.     if (server_list[i].name)
  449.         new_free(&server_list[i].name);
  450.     if (server_list[i].itsname)
  451.         new_free(&server_list[i].itsname);
  452.     if (server_list[i].password)
  453.         new_free(&server_list[i].password);
  454.     if (server_list[i].away)
  455.         new_free(&server_list[i].away);
  456.     if (server_list[i].version_string)
  457.         new_free(&server_list[i].version_string);
  458.     if (server_list[i].nickname)
  459.         new_free(&server_list[i].nickname);
  460.     if (server_list[i].whois_stuff.nick)
  461.         new_free(&server_list[i].whois_stuff.nick);
  462.     if (server_list[i].whois_stuff.user)
  463.         new_free(&server_list[i].whois_stuff.user);
  464.     if (server_list[i].whois_stuff.host)
  465.         new_free(&server_list[i].whois_stuff.host);
  466.     if (server_list[i].whois_stuff.channel)
  467.         new_free(&server_list[i].whois_stuff.channel);
  468.     if (server_list[i].whois_stuff.channels)
  469.         new_free(&server_list[i].whois_stuff.channels);
  470.     if (server_list[i].whois_stuff.name)
  471.         new_free(&server_list[i].whois_stuff.name);
  472.     if (server_list[i].whois_stuff.server)
  473.         new_free(&server_list[i].whois_stuff.server);
  474.     if (server_list[i].whois_stuff.server_stuff)
  475.         new_free(&server_list[i].whois_stuff.server_stuff);
  476.     bcopy((char *) &server_list[i + 1], (char *) &server_list[i], 
  477.         (number_of_servers - i) * sizeof(Server));
  478.     server_list = (Server *) new_realloc(server_list,
  479.         --number_of_servers * sizeof(Server));
  480.  
  481.     /* update all he structs with server in them */
  482.     channel_server_delete(i);
  483. #ifndef _Windows
  484.     exec_server_delete(i);
  485. #endif
  486.     while ((tmp = traverse_all_windows(&flag, &ti)) != NULL)
  487.         if (tmp->server > i)
  488.             tmp->server--;
  489. }
  490.  
  491. /*
  492.  * parse_server_info:  This parses a single string of the form
  493.  * "server:portnum:password:nickname".  It the points port to the portnum
  494.  * portion and password to the password portion.  This chews up the original
  495.  * string, so * upon return, name will only point the the name.  If portnum
  496.  * or password are missing or empty,  their respective returned value will
  497.  * point to null. 
  498.  */
  499. void
  500. parse_server_info(name, port, password, nick)
  501.     char    *name,
  502.         **port,
  503.         **password,
  504.         **nick;
  505. {
  506.     char *ptr;
  507.  
  508.     *port = *password = *nick = NULL;
  509.     if ((ptr = (char *) index(name, ':')) != NULL)
  510.     {
  511.         *(ptr++) = (char) 0;
  512.         if (strlen(ptr) == 0)
  513.             *port = (char *) 0;
  514.         else
  515.         {
  516.             *port = ptr;
  517.             if ((ptr = (char *) index(ptr, ':')) != NULL)
  518.             {
  519.                 *(ptr++) = (char) 0;
  520.                 if (strlen(ptr) == 0)
  521.                     *password = '\0';
  522.                 else
  523.                 {
  524.                     *password = ptr;
  525.                     if ((ptr = (char *) index(ptr, ':'))
  526.                             != NULL)
  527.                     {
  528.                         *(ptr++) = '\0';
  529.                         if (!strlen(ptr))
  530.                             *nick = NULL;
  531.                         else
  532.                             *nick = ptr;
  533.                     }
  534.                 }
  535.             }
  536.         }
  537.     }
  538. }
  539.  
  540. /*
  541.  * build_server_list: given a whitespace separated list of server names this
  542.  * builds a list of those servers using add_to_server_list().  Since
  543.  * add_to_server_list() is used to added each server specification, this can
  544.  * be called many many times to add more servers to the server list.  Each
  545.  * element in the server list case have one of the following forms: 
  546.  *
  547.  * servername 
  548.  *
  549.  * servername:port 
  550.  *
  551.  * servername:port:password 
  552.  *
  553.  * servername::password 
  554.  *
  555.  * Note also that this routine mucks around with the server string passed to it,
  556.  * so make sure this is ok 
  557.  */
  558. void
  559. build_server_list(servers)
  560.     char    *servers;
  561. {
  562.     char    *host,
  563.         *rest,
  564.         *password = (char *) 0,
  565.         *port = (char *) 0,
  566.         *nick = (char *) 0;
  567.     int    port_num;
  568.  
  569.     if (servers == (char *) 0)
  570.         return;
  571.     /* port_num = irc_port; */
  572.     while (servers)
  573.     {
  574.         if ((rest = (char *) index(servers, '\n')) != NULL)
  575.             *rest++ = '\0';
  576.         while ((host = next_arg(servers, &servers)) != NULL)
  577.         {
  578.             parse_server_info(host, &port, &password, &nick);
  579.             if (port && *port)
  580.                 port_num = atoi(port);
  581.             else
  582.                 port_num = irc_port;
  583.             add_to_server_list(host, port_num, password, nick, 0);
  584.         }
  585.         servers = rest;
  586.     }
  587. }
  588.  
  589. /*
  590.  * connect_to_server_direct: handles the tcp connection to a server.  If
  591.  * successful, the user is disconnected from any previously connected server,
  592.  * the new server is added to the server list, and the user is registered on
  593.  * the new server.  If connection to the server is not successful,  the
  594.  * reason for failure is displayed and the previous server connection is
  595.  * resumed uniterrupted. 
  596.  *
  597.  * This version of connect_to_server() connects directly to a server 
  598.  *
  599.  */
  600. static    int
  601. connect_to_server_direct(server_name, port)
  602.     char    *server_name;
  603.     int    port;
  604. {
  605.     int    new_des;
  606.     struct sockaddr_in localaddr;
  607.     int    address_len;
  608.  
  609.     using_server_process = 0;
  610.     oper_command = 0;
  611.     errno = 0;
  612. #ifdef HAVE_SYS_UN_H
  613.     if (*server_name == '/')
  614.         new_des = connect_to_unix(port, server_name);
  615.     else
  616. #endif /* HAVE_SYS_UN_H */
  617.         new_des = connect_by_number(port, server_name);
  618.     if (new_des < 0)
  619.     {
  620.         say("Unable to connect to port %d of server %s: %s", port,
  621.                 server_name, errno ? strerror(errno) :
  622.                 "unknown host");
  623.         if ((from_server != -1)&& (server_list[from_server].read != -1))
  624.             say("Connection to server %s resumed...",
  625.                     server_list[from_server].name);
  626.         return (-1);
  627.     }
  628.     if (never_connected
  629. #ifdef HAVE_SYS_UN_H
  630.          && *server_name != '/'
  631. #endif /* HAVE_SYS_UN_H */
  632.                     )
  633.     {
  634.         address_len = sizeof(struct sockaddr_in);
  635.         getsockname(new_des, (struct sockaddr *) &localaddr,
  636.                 &address_len);
  637.         local_ip_address.s_addr = ntohl(localaddr.sin_addr.s_addr);
  638.     }
  639.     update_all_status();
  640.     add_to_server_list(server_name, port, (char *) 0, (char *) 0, 1);
  641.     if (port)
  642.     {
  643.         server_list[from_server].read = new_des;
  644.         server_list[from_server].write = new_des;
  645.     }
  646.     else
  647.         /* port= */ server_list[from_server].read = new_des;
  648.     server_list[from_server].operator = 0;
  649.     return (0);
  650. }
  651.  
  652. /*
  653.  * connect_to_server_process: handles the tcp connection to a server.  If
  654.  * successful, the user is disconnected from any previously connected server,
  655.  * the new server is added to the server list, and the user is registered on
  656.  * the new server.  If connection to the server is not successful,  the
  657.  * reason for failure is displayed and the previous server connection is
  658.  * resumed uniterrupted. 
  659.  *
  660.  * This version of connect_to_server() uses the ircserv process to talk to a
  661.  * server 
  662.  */
  663. static    int
  664. connect_to_server_process(server_name, port)
  665.     char    *server_name;
  666.     int    port;
  667. {
  668. #ifdef _Windows
  669.     return -1;
  670. #else
  671.     int    write_des[2],
  672.         read_des[2],
  673.         pid,
  674.         c;
  675.     char    *path,
  676.         *name = (char *) 0,
  677.         *s;
  678.     int    old_timeout;
  679.  
  680.     path = IRCSERV_PATH;
  681.     if ((s = rindex(path, '/')) != NULL)
  682.         malloc_strcpy(&name, s + 1);
  683.     if (!name)
  684.         name = path;
  685.     if (*path == '\0')
  686.         return (connect_to_server_direct(server_name, port));
  687.     using_server_process = 1;
  688.     oper_command = 0;
  689.     write_des[0] = -1;
  690.     write_des[1] = -1;
  691.     if (pipe(write_des) || pipe(read_des))
  692.     {
  693.         if (write_des[0] != -1)
  694.         {
  695.             close(write_des[0]);
  696.             close(write_des[1]);
  697.         }
  698.         say("Couldn't start new process: %s", strerror(errno));
  699.         return (connect_to_server_direct(server_name, port));
  700.     }
  701.     switch (pid = fork())
  702.     {
  703.     case -1:
  704.         say("Couldn't start new process: %s\n", strerror(errno));
  705.         return (-1);
  706.     case 0:
  707.         (void) MY_SIGNAL(SIGINT, SIG_IGN, 0);
  708.         dup2(read_des[1], 1);
  709.         dup2(write_des[0], 0);
  710.         close(read_des[0]);
  711.         close(write_des[1]);
  712.         sprintf(buffer, "%u", port);
  713.         setuid(getuid());
  714.         execl(path, name, server_name, buffer, (char *) 0);
  715.         printf("-5 0\n"); /* -1 - -4 returned by connect_by_number() */
  716.         fflush(stdout);
  717.         _exit(1);
  718.     default:
  719.         close(read_des[1]);
  720.         close(write_des[0]);
  721.         break;
  722.     }
  723.     old_timeout = dgets_timeout(3);
  724.     c = dgets(buffer, BIG_BUFFER_SIZE, read_des[0], (char *) 0);
  725.     (void) dgets_timeout(old_timeout);
  726.     if ((c == 0) || ((c = atoi(buffer)) != 0))
  727.     {
  728.         if (c == -5)
  729.             return (connect_to_server_direct(server_name, port));
  730.         else
  731.         {
  732.             char *ptr;
  733.  
  734.             if ((ptr = (char *) index(buffer, ' ')) != NULL)
  735.             {
  736.                 ptr++;
  737.                 if (atoi(ptr) > 0)
  738.         say("Unable to connect to port %d of server %s: %s",
  739.             port, server_name, strerror(atoi(ptr)));
  740.                 else
  741.         say("Unable to connect to port %d of server %s: Unknown host",
  742.                             port, server_name);
  743.             }
  744.             else
  745.         say("Unable to connect to port %d of server %s: Unknown host",
  746.                             port, server_name);
  747.             if ((from_server != -1) &&
  748.                     (server_list[from_server].read != -1))
  749.                 say("Connection to server %s resumed...",
  750.                         server_list[from_server].name);
  751.             close(read_des[0]);
  752.             close(write_des[1]);
  753.             return (-1);
  754.         }
  755.     }
  756.     update_all_status();
  757.     add_to_server_list(server_name, port, (char *) 0, (char *) 0, 1);
  758.     server_list[from_server].read = read_des[0];
  759.     server_list[from_server].write = write_des[1];
  760.     server_list[from_server].pid = pid;
  761.     server_list[from_server].operator = 0;
  762.     return (0);
  763. #endif
  764. }
  765.  
  766. /*
  767.  * connect_to_server: Given a name and portnumber, this will attempt to
  768.  * connect to that server using either a direct connection or process
  769.  * connection, depending on the value of using_server_process.  If connection
  770.  * is successful, the proper NICK, USER, and PASS commands are sent to the
  771.  * server.  If the c_server parameter is not -1, then the server with that
  772.  * index will be closed upon successful connection here. Also, if connection
  773.  * is successful, the attempting_to_connect variable is incremented.  This is
  774.  * checked in the notice.c routines to make sure that connection was truely
  775.  * successful (and not closed immediately by the server). 
  776.  */
  777. int
  778. connect_to_server(server_name, port, c_server)
  779.     char    *server_name;
  780.     int    port;
  781.     int    c_server;
  782. {
  783.     int    index;
  784.  
  785.     message_from((char *) 0, LOG_CURRENT);
  786.     index = find_in_server_list(server_name, port);
  787.     attempting_to_connect++;
  788.     if (index == -1 || server_list[index].read == -1)
  789.     {
  790.         if (port == -1)
  791.         {
  792.             if (index != -1)
  793.                 port = server_list[index].port;
  794.             else
  795.                 port = irc_port;
  796.         }
  797.         say("Connecting to port %d of server %s", port, server_name);
  798.         if (using_server_process)
  799.             index = connect_to_server_process(server_name, port);
  800.         else
  801.             index = connect_to_server_direct(server_name, port);
  802.         if (index)
  803.         {
  804.             attempting_to_connect--;
  805.             return -1;
  806.         }
  807.         if ((c_server != -1) && (c_server != from_server))
  808.             close_server(c_server, "changing servers");
  809.         if (connect_next_nick && *connect_next_nick)
  810.         {
  811.             malloc_strcpy(&(server_list[from_server].nickname),
  812.                     connect_next_nick);
  813.             new_free(&connect_next_nick);
  814.         }
  815.         if (server_list[from_server].nickname == (char *) 0)
  816.             malloc_strcpy(&(server_list[from_server].nickname),
  817.                     nickname);
  818.         send_to_server("NICK %s", server_list[from_server].nickname);
  819.         if (server_list[from_server].password)
  820.             send_to_server("PASS %s",
  821.                     server_list[from_server].password);
  822.         send_to_server("USER %s %s %s :%s", username,
  823.             (send_umode && *send_umode) ? send_umode : hostname,
  824.             server_list[from_server].name, realname);
  825.     }
  826.     else
  827.     {
  828.         say("Connected to port %d of server %s", port, server_name);
  829.         from_server = index;
  830.     }
  831.     message_from((char *) 0, LOG_CRAP);
  832.     update_all_status();
  833.     return 0;
  834. }
  835.  
  836. /*
  837.  * get_connected: This function connects the primary server for IRCII.  It
  838.  * attempts to connect to the given server.  If this isn't possible, it
  839.  * traverses the server list trying to keep the user connected at all cost.  
  840.  */
  841. void
  842. get_connected(server)
  843.     int    server;
  844. {
  845.     int    s,
  846.         ret = -1;
  847.  
  848.     if (server_list)
  849.     {
  850.         if (server == number_of_servers)
  851.             server = 0;
  852.         else if (server < 0)
  853.             server = number_of_servers - 1;
  854.         s = server;
  855.         if (connect_to_server(server_list[server].name, server_list[server].port, primary_server))
  856.         {
  857.             while (server_list[server].read == -1)
  858.             {
  859.                 server++;
  860.                 if (server == number_of_servers)
  861.                     server = 0;
  862.                 if (server == s)
  863.                 {
  864.                     clean_whois_queue();
  865.                     say("Use /SERVER to connect to a server");
  866.                     break;
  867.                 }
  868.                 from_server = server;
  869.                 ret = connect_to_server(server_list[server].name, server_list[server].port, primary_server);
  870.             }
  871.             if (!ret)
  872.                 from_server = server;
  873.             else
  874.                 from_server = -1;
  875.         }
  876.         change_server_channels(primary_server, from_server);
  877.         set_window_server(-1, from_server, 1);
  878.     }
  879.     else
  880.     {
  881.         clean_whois_queue();
  882.         say("Use /SERVER to connect to a server");
  883.     }
  884. }
  885.  
  886. #ifdef SERVERS_FILE
  887. /*
  888.  * read_server_file: reads hostname:portnum:password server information from
  889.  * a file and adds this stuff to the server list.  See build_server_list()/ 
  890.  */
  891. int
  892. read_server_file()
  893. {
  894.     FILE *fp;
  895.     char format[11];
  896.     char *file_path = (char *) 0;
  897.  
  898.     malloc_strcpy(&file_path, irc_lib);
  899.     malloc_strcat(&file_path, SERVERS_FILE);
  900.     sprintf(format, "%%%ds", BIG_BUFFER_SIZE);
  901.     fp = fopen(file_path, "r");
  902.     new_free(&file_path);
  903.     if ((FILE *) 0 != fp)
  904.     {
  905.         while (fscanf(fp, format, buffer) != EOF)
  906.             build_server_list(buffer);
  907.         fclose(fp);
  908.         return (0);
  909.     }
  910.     return (1);
  911. }
  912. #endif
  913.  
  914. /* display_server_list: just guess what this does */
  915. void
  916. display_server_list()
  917. {
  918.     int    i;
  919.  
  920.     if (server_list)
  921.     {
  922.         if (from_server != -1)
  923.             say("Current server: %s %d",
  924.                     server_list[from_server].name,
  925.                     server_list[from_server].port);
  926.         else
  927.             say("Current server: <None>");
  928.         if (primary_server != -1)
  929.             say("Primary server: %s %d",
  930.                 server_list[primary_server].name,
  931.                 server_list[primary_server].port);
  932.         else
  933.             say("Primary server: <None>");
  934.         say("Server list:");
  935.         for (i = 0; i < number_of_servers; i++)
  936.         {
  937.             if (!server_list[i].nickname)
  938.             {
  939.                 if (server_list[i].read == -1)
  940.                     say("\t%d) %s %d", i,
  941.                         server_list[i].name,
  942.                         server_list[i].port);
  943.                 else
  944.                     say("\t%d) %s %d", i,
  945.                         server_list[i].name,
  946.                         server_list[i].port);
  947.             }
  948.             else
  949.             {
  950.                 if (server_list[i].read == -1)
  951.                     say("\t%d) %s %d (was %s)", i,
  952.                         server_list[i].name,
  953.                         server_list[i].port,
  954.                         server_list[i].nickname);
  955.                 else
  956.                     say("\t%d) %s %d (%s)", i,
  957.                         server_list[i].name,
  958.                         server_list[i].port,
  959.                         server_list[i].nickname);
  960.             }
  961.         }
  962.     }
  963.     else
  964.         say("The server list is empty");
  965. }
  966.  
  967. void
  968. MarkAllAway(command, message)
  969.     char    *command;
  970.     char    *message;
  971. {
  972.     int    old_server;
  973.  
  974.     old_server = from_server;
  975.     for (from_server=0; from_server<number_of_servers; from_server++)
  976.     {
  977.         if (server_list[from_server].connected)
  978.             send_to_server("%s :%s", command, message);
  979.     }
  980.     from_server = old_server;
  981. }
  982.  
  983.  
  984. /*
  985.  * set_server_password: this sets the password for the server with the given
  986.  * index.  If password is null, the password for the given server is returned 
  987.  */
  988. char    *
  989. set_server_password(index, password)
  990.     int    index;
  991.     char    *password;
  992. {
  993.  
  994.     if (server_list)
  995.     {
  996.         if (password)
  997.             malloc_strcpy(&(server_list[index].password), password);
  998.         return (server_list[index].password);
  999.     }
  1000.     else
  1001.         return ((char *) 0);
  1002. }
  1003.  
  1004. /* server_list_size: returns the number of servers in the server list */
  1005. int
  1006. server_list_size()
  1007. {
  1008.     return (number_of_servers);
  1009. }
  1010.  
  1011. #ifdef DYNAMIC_SLIP
  1012. extern char MyHostName[80];
  1013. extern struct    in_addr    MyHostAddr;        /* The local machine address */
  1014. #endif
  1015. /*
  1016.  * server: the /SERVER command. Read the SERVER help page about 
  1017.  */
  1018. /*ARGSUSED*/
  1019. void
  1020. server(command, args)
  1021.     char    *command,
  1022.         *args;
  1023. {
  1024.     char    *server,
  1025.         *port;
  1026.     int    port_num,
  1027.         i;
  1028. #ifdef DYNAMIC_SLIP
  1029.     struct hostent *hp;
  1030. #endif
  1031.  
  1032.     if ((server = next_arg(args, &args)) != NULL)
  1033.     {
  1034.     /*
  1035.     ** Nasty hack for use with dynamic SLIP servers
  1036.     */
  1037. #ifdef DYNAMIC_SLIP
  1038.         gethostname(MyHostName, sizeof(MyHostName));
  1039.         if ((hp = gethostbyname(MyHostName)) != NULL)
  1040.         {
  1041.             bcopy(hp->h_addr, (char *) &MyHostAddr, sizeof(MyHostAddr));
  1042.             local_ip_address.s_addr = ntohl(MyHostAddr.s_addr);
  1043.         }
  1044. #endif
  1045.         if (*server == '-')
  1046.         {
  1047.             if (!my_strnicmp(server + 1, "DELETE", strlen(server + 1)))
  1048.             {
  1049.                 if ((server = next_arg(args, &args)) != NULL)
  1050.                 {
  1051.                     if ((i = parse_server_index(server)) == -1)
  1052.                     {
  1053.                     if (-1 == (i =
  1054.                         find_in_server_list(server, 0)))
  1055.                     {
  1056.                         say("No such server in list");
  1057.                         return;
  1058.                     }
  1059.                     }
  1060.                     if (server_list[i].connected)
  1061.                     {
  1062.             say("Can not delete server that is already open");
  1063.             return;
  1064.                     }
  1065.                     remove_from_server_list(i);
  1066.                     return;
  1067.                 }
  1068.                 say("Need server number for -DELETE");
  1069.                 return;
  1070.             }
  1071.         }
  1072.         if ((port = next_arg(args, &args)) != NULL)
  1073.             port_num = atoi(port);
  1074.         else
  1075.             port_num = irc_port;
  1076.         if (*server == '+')
  1077.         {
  1078.             if (*(++server))
  1079.             {
  1080.                 if ((i = parse_server_index(server)) != -1)
  1081.                 {
  1082.                     server = server_list[i].name;
  1083.                     port_num = server_list[i].port;
  1084.                 }
  1085.                 if (!connect_to_server(server, port_num, -1))
  1086.                 {
  1087.                     set_window_server(0, from_server, 0);
  1088. #ifndef PHONE
  1089.                     set_level_by_refnum(0, LOG_ALL);
  1090. #else
  1091.                     set_level_by_refnum(0, LOG_NONE);
  1092. #endif
  1093.                 }
  1094.                 return;
  1095.             }
  1096.             get_connected(primary_server + 1);
  1097.             return;
  1098.         }
  1099.         else if (*server == '-')
  1100.         {
  1101.             if (*(++server))
  1102.             {
  1103.                 int    i;
  1104.  
  1105.                 if ((i = parse_server_index(server)) == -1)
  1106.                 {
  1107.                     if ((i = find_in_server_list(server,
  1108.                         port_num)) == -1)
  1109.                     {
  1110.                         say("No such server in server list: %s", server);
  1111.                         return;
  1112.                     }
  1113.                 }
  1114.                 if (i == primary_server)
  1115.                 {
  1116.                     say("You can't close your primary server!");
  1117.                     return;
  1118.                 }
  1119.                 close_server(i, "closing server");
  1120.                 window_check_servers();
  1121.                 return;
  1122.             }
  1123.             get_connected(primary_server - 1);
  1124.             return;
  1125.         }
  1126.         if ((i = parse_server_index(server)) != -1)
  1127.         {
  1128.             server = server_list[i].name;
  1129.             port_num = server_list[i].port;
  1130.         }
  1131.         if (connect_to_server(server, port_num, primary_server) != -1)
  1132.         {
  1133.             change_server_channels(primary_server, from_server);
  1134.             if (primary_server > -1 && from_server != primary_server &&
  1135.                 !server_list[from_server].away && server_list[primary_server].away)
  1136.                 malloc_strcpy(&server_list[from_server].away, server_list[primary_server].away);
  1137.             set_window_server(-1, from_server, 1);
  1138.         }
  1139.     }
  1140.     else
  1141.         display_server_list();
  1142. }
  1143.  
  1144. /*
  1145.  * flush_server: eats all output from server, until there is at least a
  1146.  * second delay between bits of servers crap... useful to abort a /links. 
  1147.  */
  1148. void
  1149. flush_server()
  1150. {
  1151.     fd_set rd;
  1152.     struct timeval timeout;
  1153.     int    flushing = 1;
  1154.     int    des;
  1155.     int    old_timeout;
  1156.  
  1157.     if ((des = server_list[from_server].read) == -1)
  1158.         return;
  1159.     timeout.tv_usec = 0;
  1160.     timeout.tv_sec = 1;
  1161.     old_timeout = dgets_timeout(1);
  1162.     while (flushing)
  1163.     {
  1164.         FD_ZERO(&rd);
  1165.         FD_SET(des, &rd);
  1166.         switch (new_select(&rd, (fd_set *) 0, &timeout))
  1167.         {
  1168.         case -1:
  1169.         case 0:
  1170.             flushing = 0;
  1171.             break;
  1172.         default:
  1173.             if (FD_ISSET(des, &rd))
  1174.             {
  1175.                 if (0 == dgets(buffer, BIG_BUFFER_SIZE, des,
  1176.                         (char *) 0))
  1177.                     flushing = 0;
  1178.                 
  1179.             }
  1180.             break;
  1181.         }
  1182.     }
  1183.     /* make sure we've read a full line from server */
  1184.     FD_ZERO(&rd);
  1185.     FD_SET(des, &rd);
  1186.     if (new_select(&rd, (fd_set *) 0, &timeout) > 0)
  1187.         dgets(buffer, BIG_BUFFER_SIZE, des, (char *) 0);
  1188.     (void) dgets_timeout(old_timeout);
  1189. }
  1190.  
  1191. /*
  1192.  * set_server_whois: sets the whois value for the given server index.  If the
  1193.  * whois value is 0, it assumes the server doesn't send End of WHOIS commands
  1194.  * and the whois.c routines use the old fashion way of getting whois info. If
  1195.  * the whois value is non-zero, then the server sends End of WHOIS and things
  1196.  * can be done more effienciently 
  1197.  */
  1198. void
  1199. set_server_whois(index, value)
  1200.     int    index,
  1201.         value;
  1202. {
  1203.     server_list[index].whois = value;
  1204. }
  1205.  
  1206. /* get_server_whois: Returns the whois value for the given server index */
  1207. int
  1208. get_server_whois(index)
  1209.     int    index;
  1210. {
  1211.     if (index == -1)
  1212.         index = primary_server;
  1213.     return (server_list[index].whois);
  1214. }
  1215.  
  1216.  
  1217. void
  1218. set_server_2_6_2(index, value)
  1219.     int    index,
  1220.         value;
  1221. {
  1222.     set_server_flag(index, SERVER_2_6_2, value);
  1223. }
  1224.  
  1225. int
  1226. get_server_2_6_2(index)
  1227.     int    index;
  1228. {
  1229.     if (index == -1)
  1230.         index = primary_server;
  1231.     return (get_server_flag(index, SERVER_2_6_2));
  1232. }
  1233.  
  1234. void
  1235. set_server_flag(index, flag, value)
  1236.     int    index;
  1237.     int    flag;
  1238.     int    value;
  1239. {
  1240.     if (index == -1)
  1241.         index = primary_server;
  1242.     if (value)
  1243.         server_list[index].flags |= flag;
  1244.     else
  1245.         server_list[index].flags &= ~flag;
  1246. }
  1247.  
  1248. int
  1249. get_server_flag(index, value)
  1250.     int    index;
  1251.     int    value;
  1252. {
  1253.     if (index == -1)
  1254.         index = primary_server;
  1255.     return server_list[index].flags & value;
  1256. }
  1257.  
  1258. /*
  1259.  * set_server_version: Sets the server version for the given server type.  A
  1260.  * zero version means pre 2.6, a one version means 2.6 aso. (look server.h
  1261.  * for typedef)
  1262.  */
  1263. void
  1264. set_server_version(index, version)
  1265.     int    index;
  1266.     int    version;
  1267. {
  1268.     if (index == -1)
  1269.         index = primary_server;
  1270.     server_list[index].version = version;
  1271. }
  1272.  
  1273. /*
  1274.  * get_server_version: returns the server version value for the given server
  1275.  * index 
  1276.  */
  1277. int
  1278. get_server_version(index)
  1279.     int    index;
  1280. {
  1281.     if (index == -1)
  1282.         index = primary_server;
  1283.     return (server_list[index].version);
  1284. }
  1285.  
  1286. /* get_server_name: returns the name for the given server index */
  1287. char    *
  1288. get_server_name(index)
  1289.     int    index;
  1290. {
  1291.     if (index == -1)
  1292.         index = primary_server;
  1293.     return (server_list[index].name);
  1294. }
  1295.  
  1296. /* set_server_itsname: returns the server's idea of its name */
  1297. char    *
  1298. get_server_itsname(index)
  1299.     int    index;
  1300. {
  1301.     if (index==-1)
  1302.         index=primary_server;
  1303.     if (server_list[index].itsname)
  1304.         return server_list[index].itsname;
  1305.     else
  1306.         return server_list[index].name;
  1307. }
  1308.  
  1309. void
  1310. set_server_itsname(index, name)
  1311.     int    index;
  1312.     char    *name;
  1313. {
  1314.     if (index==-1)
  1315.         index=primary_server;
  1316.     malloc_strcpy(&server_list[index].itsname, name);
  1317. }
  1318.  
  1319. /*
  1320.  * is_server_open: Returns true if the given server index represents a server
  1321.  * with a live connection, returns false otherwise 
  1322.  */
  1323. int
  1324. is_server_open(index)
  1325.     int    index;
  1326. {
  1327.     if (index < 0) return (0);
  1328.         return (server_list[index].read != -1);
  1329. }
  1330.  
  1331. /*
  1332.  * is_server_connected: returns true if the given server is connected.  This
  1333.  * means that both the tcp connection is open and the user is properly
  1334.  * registered 
  1335.  */
  1336. int
  1337. is_server_connected(index)
  1338.     int    index;
  1339. {
  1340.     return (server_list[index].connected);
  1341. }
  1342.  
  1343. /* get_server_port: Returns the connection port for the given server index */
  1344. int
  1345. get_server_port(index)
  1346.     int    index;
  1347. {
  1348.     if (index == -1)
  1349.         index = primary_server;
  1350.     return (server_list[index].port);
  1351. }
  1352.  
  1353. /*
  1354.  * get_server_nickname: returns the current nickname for the given server
  1355.  * index 
  1356.  */
  1357. char    *
  1358. get_server_nickname(index)
  1359.     int    index;
  1360. {
  1361.     if ((index != -1) && server_list[index].nickname)
  1362.         return (server_list[index].nickname);
  1363.     else
  1364.         return (nickname);
  1365. }
  1366.  
  1367.  
  1368.  
  1369. /* get_server_qhead - get the head of the whois queue */
  1370. WhoisQueue *
  1371. get_server_qhead(index)
  1372.     int    index;
  1373. {
  1374.     if (index != -1)
  1375.         return server_list[index].WQ_head;
  1376.     else
  1377.         return WQ_head;
  1378. }
  1379.  
  1380. /* get_server_whois_stuff */
  1381. WhoisStuff *
  1382. get_server_whois_stuff(index)
  1383.     int    index;
  1384. {
  1385.     if (index == -1)
  1386.         index=primary_server;
  1387.     return &server_list[index].whois_stuff;
  1388. }
  1389.  
  1390. /* get_server_qtail - get the tail of the whois queue */
  1391. WhoisQueue *
  1392. get_server_qtail(index)
  1393.     int    index;
  1394. {
  1395.     if (index !=-1)
  1396.         return server_list[index].WQ_tail;
  1397.     else
  1398.         return WQ_tail;
  1399. }
  1400.  
  1401.  
  1402.  
  1403. /* set_server_qhead - set the head of the whois queue */
  1404. void
  1405. set_server_qhead(index, value)
  1406.     int    index;
  1407.     WhoisQueue *value;
  1408. {
  1409.     if (index != -1)
  1410.         server_list[index].WQ_head=value;
  1411.     else
  1412.         WQ_head=value;
  1413. }
  1414.  
  1415. /* set_server_qtail - set the tail of the whois queue */
  1416. void
  1417. set_server_qtail(index, value)
  1418.     int    index;
  1419.     WhoisQueue *value;
  1420. {
  1421.     if (index !=-1)
  1422.         server_list[index].WQ_tail=value;
  1423.     else
  1424.         WQ_tail=value;
  1425. }
  1426.  
  1427.  
  1428.  
  1429. /*
  1430.  * get_server_operator: returns true if the user has op privs on the server,
  1431.  * false otherwise 
  1432.  */
  1433. int
  1434. get_server_operator(index)
  1435.     int    index;
  1436. {
  1437.     return (server_list[index].operator);
  1438. }
  1439.  
  1440. /*
  1441.  * set_server_operator: If flag is non-zero, marks the user as having op
  1442.  * privs on the given server.  
  1443.  */
  1444. void
  1445. set_server_operator(index, flag)
  1446.     int    index;
  1447.     int    flag;
  1448. {
  1449.     server_list[index].operator = flag;
  1450. }
  1451.  
  1452. /*
  1453.  * set_server_nickname: sets the nickname for the given server to nickname.
  1454.  * This nickname is then used for all future connections to that server
  1455.  * (unless changed with NICK while connected to the server 
  1456.  */
  1457. void
  1458. set_server_nickname(index, nick)
  1459.     int    index;
  1460.     char    *nick;
  1461. {
  1462.     if (index != -1)
  1463.     {
  1464.         malloc_strcpy(&(server_list[index].nickname), nick);
  1465.         if (index == primary_server)
  1466.             strmcpy(nickname,nick,NICKNAME_LEN);
  1467.     }
  1468.     update_all_status();
  1469. }
  1470.  
  1471. void
  1472. set_server_motd(index,flag)
  1473.     int    index;
  1474.     int    flag;
  1475. {
  1476.     if (index != -1)
  1477.         server_list[index].motd = flag;
  1478. }
  1479.  
  1480. int
  1481. get_server_motd(index)
  1482.     int    index;
  1483. {
  1484.     if (index != -1)
  1485.         return(server_list[index].motd);
  1486.     return (0);
  1487. }
  1488.  
  1489. void
  1490. server_is_connected(index, value)
  1491.     int    index,
  1492.         value;
  1493. {
  1494.     server_list[index].connected = value;
  1495.     if (value)
  1496.         server_list[index].eof = 0;
  1497. }
  1498.  
  1499. /* send_to_server: sends the given info the the server */
  1500. void
  1501. #ifdef USE_STDARG_H
  1502. send_to_server(char *format, ...)
  1503. #else
  1504. send_to_server(format, arg1, arg2, arg3, arg4, arg5,
  1505.         arg6, arg7, arg8, arg9, arg10)
  1506.     char    *format;
  1507.     char    *arg1,
  1508.         *arg2,
  1509.         *arg3,
  1510.         *arg4,
  1511.         *arg5,
  1512.         *arg6,
  1513.         *arg7,
  1514.         *arg8,
  1515.         *arg9,
  1516.         *arg10;
  1517. #endif
  1518. {
  1519.     define_big_buffer(buffer);    /* make this buffer *much*
  1520.                      * bigger than needed */
  1521.     char    *buf = buffer;
  1522.     int    len,
  1523.         des;
  1524.     int    server;
  1525. #ifdef USE_STDARG_H
  1526.     va_list vlist;
  1527.  
  1528.     va_start(vlist, format);
  1529. #endif
  1530.  
  1531.     if ((server = from_server) == -1)
  1532.         server = primary_server;
  1533.     if (server != -1 && ((des = server_list[server].write) != -1))
  1534.     {
  1535.         server_list[server].sent = 1;
  1536. #ifdef USE_STDARG_H
  1537.         vsprintf(buf, format, vlist);
  1538.         va_end(vlist);
  1539. #else
  1540.                  
  1541.         sprintf(buf, format, arg1, arg2, arg3, arg4, arg5,
  1542.             arg6, arg7, arg8, arg9, arg10);
  1543. #endif
  1544.         len = strlen(buffer);
  1545.         if (len > (IRCD_BUFFER_SIZE - 2))
  1546.             buffer[IRCD_BUFFER_SIZE - 2] = (char) 0;
  1547.         strmcat(buffer, "\n", IRCD_BUFFER_SIZE);
  1548.         send(des, buffer, strlen(buffer), 0);
  1549.     }
  1550.     else
  1551.         say("You are not connected to a server, use /SERVER to connect.");
  1552.     free_big_buffer(buffer);
  1553. }
  1554.  
  1555. #ifdef HAVE_SYS_UN_H
  1556. /*
  1557.  * Connect to a UNIX domain socket. Only works for servers.
  1558.  * submitted by Avalon for use with server 2.7.2 and beyond.
  1559.  */
  1560. int
  1561. connect_to_unix(port, path)
  1562.     int    port;
  1563.     char    *path;
  1564. {
  1565.     struct    sockaddr_un un;
  1566.     int        sock;
  1567.  
  1568.     sock = socket(AF_UNIX, SOCK_STREAM, 0);
  1569.  
  1570.     un.sun_family = AF_UNIX;
  1571.     sprintf(un.sun_path, "%-.100s/%-.6d", path, port);
  1572.  
  1573.     if (connect(sock, (struct sockaddr *)&un, strlen(path)+2) == -1)
  1574.     {
  1575.         close(sock);
  1576.         return -1;
  1577.     }
  1578.     return sock;
  1579. }
  1580. #endif /* HAVE_SYS_UN_H */
  1581.  
  1582. /*
  1583.  * close_all_server: Used whn creating new screens to close all the open
  1584.  * server connections in the child process...
  1585.  */
  1586. extern    void
  1587. close_all_server()
  1588. {
  1589.     int    i;
  1590.  
  1591.     for (i = 0; i < number_of_servers; i++)
  1592.     {
  1593.         if (server_list[i].read != -1)
  1594.             new_close(server_list[i].read);
  1595.         if (server_list[i].write != -1)
  1596.             new_close(server_list[i].write);
  1597.     }
  1598. }
  1599.  
  1600. extern    char    *
  1601. create_server_list()
  1602. {
  1603.     int    i;
  1604.     char    *value = (char *) 0;
  1605.  
  1606.     *buffer = '\0';
  1607.     for (i = 0; i < number_of_servers; i++)
  1608.         if (server_list[i].read != -1)
  1609.         {
  1610.             strcat(buffer, server_list[i].itsname);
  1611.             strcat(buffer, " ");
  1612.         }
  1613.     malloc_strcpy(&value, buffer);
  1614.  
  1615.     return value;
  1616. }
  1617.  
  1618. static    void
  1619. add_to_server_buffer(server, buf)
  1620.     int    server;
  1621.     char    *buf;
  1622. {
  1623.     if (buf && *buf)
  1624.     {
  1625.         if (server_list[server].buffer)
  1626.             malloc_strcat(&server_list[server].buffer, buf);
  1627.         else
  1628.             malloc_strcpy(&server_list[server].buffer, buf);
  1629.     }
  1630. }
  1631.